package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.domain.po.Dept;
import com.itheima.domain.po.Emp;
import com.itheima.domain.po.EmpExpr;
import com.itheima.domain.query.EmpQueryParam;
import com.itheima.domain.vo.PageResult;
import com.itheima.mapper.DeptMapper;
import com.itheima.mapper.EmpExprMapper;
import com.itheima.mapper.EmpMapper;
import com.itheima.service.EmpExprService;
import com.itheima.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {
    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private EmpExprMapper empExprMapper;

    @Autowired
    private EmpExprService empExprService;

    //    @Override
    public PageResult<Emp> pageEmp1(EmpQueryParam param) {
        //1 参数校验：分页参数抛出异常
        Integer PageNum = param.getPage();
        Integer pageSize = param.getPageSize();
        if (ObjectUtils.isNull(PageNum) || ObjectUtils.isNull(pageSize)) {
            throw new RuntimeException("PageNum or pageSize is null");
        }
        String name = param.getName();
        Integer gender = param.getGender();
        LocalDate begin = param.getBegin();
        LocalDate end = param.getEnd();
        //2 分类查询：对emp条件分页查询List<Emp>-->循环遍历，根据dept_id查询dept表获取部门名称填充deptName
        // 2.1分页查询
        // 等价sQL: select * from emp where name like “%? %" and user_sex=? order by update_time desc limit ?.?
        Page<Emp> page = Page.of(PageNum, pageSize);
        //queryWrapper 链式调用构建查询条件
/*        QueryWrapper<Emp> queryWrapper = Wrappers.<Emp>query()
                .like(StringUtils.isNotBlank(name), "name", name)
                .eq(gender != null, "gender", gender)
                .between(begin != null && end != null && end.isAfter(begin), "entry_date", begin, end)
                .orderByDesc("update_time");*/

        //LambdaQueryWrapper 使用方法引用来替代直接写入字段名 起到解耦的作用
/*        LambdaQueryWrapper<Emp> empLambdaQueryWrapper = Wrappers.<Emp>lambdaQuery()
                .like(StringUtils.isNotBlank(name), Emp::getName, name)
                .eq(gender != null, Emp::getGender, gender)
                .between(begin != null && end != null && end.isAfter(begin), Emp::getEntryDate, begin, end)
                .orderByDesc(Emp::getUpdateTime);
        this.page(page, empLambdaQueryWrapper);*/

        //Service层专属方法 Mapper层没有q LambdaQueryChainWrapper=支持lambada+将条件+目标方法串起来
        this.lambdaQuery().eq(Emp::getName, name)
                .eq(gender != null, Emp::getGender, gender)
                .between(begin != null && end != null && end.isAfter(begin), Emp::getEntryDate, begin, end)
                .orderByDesc(Emp::getUpdateTime)
                .page(page);
        // 2.2 循环填充部门名称
        List<Emp> empList = page.getRecords();
        if (CollectionUtils.isNotEmpty(empList)) {
            empList.forEach(emp -> {
                Dept dept = deptMapper.selectById(emp.getDeptId());
                Assert.notNull(dept, "员工关联的部门为空");
                emp.setDeptName(dept.getName());
            });
        }
        return PageResult.<Emp>builder().total(page.getTotal()).rows(empList).build();
    }


    /**
     * 分页查询员工信息
     *
     * @param param 查询参数
     * @return 分页结果
     */
    @Override
    public PageResult<Emp> pageEmp(EmpQueryParam param) {
        //1 参数校验：分页参数抛出异常
        Integer PageNum = param.getPage();
        Integer pageSize = param.getPageSize();
        if (ObjectUtils.isNull(PageNum) || ObjectUtils.isNull(pageSize)) {
            throw new RuntimeException("PageNum or pageSize is null");
        }

        Page<Emp> page = Page.of(PageNum, pageSize);
        this.getBaseMapper().selectEmpPage(page, param);
        return PageResult.<Emp>builder().total(page.getTotal()).rows(page.getRecords()).build();
    }

    /**
     * 保存员工信息
     *
     * @param emp 要保存的员工信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveEmp(Emp emp) {
        //1 对参数进行校验
        if (ObjectUtils.isNull(emp)) {
            throw new RuntimeException("要保存的员工信息为空");
        }

        //2 保存员工信息
        emp.setPassword("123456");
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        this.save(emp);

        //3 保存员工工作经历信息
        List<EmpExpr> exprList = emp.getExprList();
        if (CollectionUtils.isNotEmpty(exprList)) {
            exprList.forEach(expr -> {
                expr.setEmpId(emp.getId());
            });
            empExprMapper.insert(exprList);
        }
    }

    /**
     * 删除员工信息
     *
     * @param ids 要删除的员工id列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeEmpByIds(List<Integer> ids) {
        //1 对参数进行校验
        if (CollectionUtils.isEmpty(ids)) {
            throw new RuntimeException("要删除的员工id列表为空");
        }
        this.removeByIds(ids);
/*        ids.forEach(id -> {
            empExprMapper.delete(Wrappers.<EmpExpr>query().eq("emp_id", id));
        });*/
        empExprService.remove(Wrappers.<EmpExpr>lambdaQuery()
                .in(EmpExpr::getEmpId, ids));
    }

    /**
     * 根据id查询员工信息
     *
     * @param id 员工id
     * @return 员工信息
     */
    @Override
    public Emp getEmpById(Integer id) {
        //1 对参数进行校验
        if (ObjectUtils.isNull(id)) {
            throw new RuntimeException("员工id为空");
        }
        Emp emp = this.getById(id);

        if (emp == null) {
            throw new RuntimeException("id对应的员工不存在");
        }

//        List<EmpExpr> exprList = empExprMapper.selectList(Wrappers.<EmpExpr>query().eq("emp_id", id));
        List<EmpExpr> exprList = empExprService.list(Wrappers.<EmpExpr>lambdaQuery()
                .eq(EmpExpr::getEmpId, id));
        emp.setExprList(exprList);
        return emp;
    }

    /**
     * 更新员工信息
     *
     * @param emp 要更新的员工信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateEmp(Emp emp) {
        //1 对参数进行校验
        if (ObjectUtils.isNull(emp) && ObjectUtils.isNull(emp.getId())) {
            throw new RuntimeException("员工信息为空或员工id不存在");
        }
        // 1-修改员工信息
        emp.setUpdateTime(LocalDateTime.now());
        this.updateById(emp);

        // 2-修改员工对应工作经历：先删除再新增
        empExprService.remove(Wrappers.<EmpExpr>lambdaQuery()
                .eq(EmpExpr::getEmpId, emp.getId()));
        List<EmpExpr> exprList = emp.getExprList();
        if (CollectionUtils.isNotEmpty(exprList)) {
            exprList.forEach(expr -> expr.setEmpId(emp.getId()));
            empExprService.saveBatch(exprList);
        }
    }
}

